package com.zhang.log4j2desensitization.config;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 拦截脱敏的日志:
 * 1，身份证
 * 2，姓名
 * 3，身份证号 （目前暂时不脱敏）
 * 4、地址
 * 脱敏规则后续可以优化在配置文件中
 *
 **/
@Component
@Slf4j
public class Log4j2Rule {

    /**
     * 正则匹配 关键词 类别
     */
    public static Map<String, String> regularMap = new HashMap<>();
    /**
     * 要匹配的正则表达式map
     */
    public static final Map<String, Pattern> REG_PATTERN_MAP = new HashMap<>();
    public static final Map<String, String> KEY_REG_MAP = new HashMap<>();
    /**
     * TODO  可配置
     * 此项可以后期放在配置项中
     */
    /**
     * 用户名脱敏关键字
     */
    public static String USER_NAME_STR;
    /**
     * 地址脱敏关键字
     */
    public static String USER_ADDRESS_STR;
    //暂时不需要脱敏身份证
    /**
     * 身份证脱敏关键字
     */
    public static String USER_IDCARD_STR;
    /**
     * 手机号脱敏关键字
     */
    public static String USER_PHONE_STR;
    /**
     * 邮箱脱敏关键字
     */
    public static String USER_MAIL_STR;

    public static String USER_BANK_CARD_STR;

    @Value("${sensitity.userNameStr}")
    private String userNameStr;
    @Value("${sensitity.userAddressStr}")
    private String userAddressStr;
    @Value("${sensitity.userIdcardStr}")
    private String userIdcardStr;
    @Value("${sensitity.userPhoneStr}")
    private String userPhoneStr;
    @Value("${sensitity.userMailStr}")
    private String userMailStr;
    @Value("${sensitity.userBankCardStr}")
    private String userBankCardStr;

    /**
     * 正则匹配，根据业务要求自定义
     */
    private static final String ID_CARD_REGEXP = "(\\d{17}[0-9Xx]|\\d{14}[0-9Xx])";
    private static final String USERNAME_REGEXP = "[\\u4e00-\\u9fa5_a-zA-Z0-9-]{2,50}";
    private static final String ADDRESS_REGEXP = "[\\u4e00-\\u9fa5_a-zA-Z0-9-]{3,200}";
    private static final String PHONE_REGEXP = "(?<!\\d)(?:(?:1[3456789]\\d{9})|(?:861[356789]\\d{9}))(?!\\d)";
    private static final String EMAIL_REGEXP = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}";
    private static final String BANK_CARD_REGEXP = "\\W\\d{14,19}\\W";


    @PostConstruct
    private void init() {
        USER_NAME_STR = userNameStr;
        USER_ADDRESS_STR = userAddressStr;
        USER_IDCARD_STR = userIdcardStr;
        USER_PHONE_STR = userPhoneStr;
        USER_MAIL_STR = userMailStr;
        USER_BANK_CARD_STR = userBankCardStr;
        regularMap.put(USER_NAME_STR, USERNAME_REGEXP);
        regularMap.put(USER_ADDRESS_STR, ADDRESS_REGEXP);
        regularMap.put(USER_IDCARD_STR, ID_CARD_REGEXP);
        regularMap.put(USER_PHONE_STR, PHONE_REGEXP);
        regularMap.put(USER_MAIL_STR, EMAIL_REGEXP);
        regularMap.put(USER_BANK_CARD_STR, BANK_CARD_REGEXP);

        try {
            if (MapUtils.isEmpty(Log4j2Rule.regularMap)) {
                return;
            }
            Log4j2Rule.regularMap.forEach((a, b) -> {
                if (StringUtils.isNotBlank(a)) {
                    Map<String, String> collect = Arrays.stream(a.split(",")).collect(Collectors.toMap(c -> c, w -> b, (key1, key2) -> key1));
                    KEY_REG_MAP.putAll(collect);
                }
                Pattern compile = Pattern.compile(b);
                REG_PATTERN_MAP.put(b, compile);
            });

        } catch (Exception e) {
            log.info(">>>>>> 初始化日志脱敏规则失败 ERROR：{0}", e);
        }
    }


}
